/**
 * 扩展管理器 - 核心业务逻辑
 */
import * as vscode from 'vscode';
import { ExtensionConfig } from './types';
import { ConfigManager } from './config';
import { Logger } from './logger';
import { PhpAnalyzer } from './phpAnalyzer';
import { DecorationManager } from './decorationManager';

/**
 * 扩展管理器类
 */
export class ExtensionManager {
    private readonly logger: Logger;
    private readonly analyzer: PhpAnalyzer;
    private readonly decorationManager: DecorationManager;
    private readonly disposables: vscode.Disposable[] = [];

    private config: ExtensionConfig;
    private activeEditor: vscode.TextEditor | undefined;
    private updateTimeout: NodeJS.Timeout | undefined;
    private isUpdating: boolean = false;

    constructor(context: vscode.ExtensionContext) {
        this.logger = Logger.getInstance();
        this.analyzer = new PhpAnalyzer();
        this.decorationManager = new DecorationManager();

        // 初始化配置
        this.config = ConfigManager.getConfig();
        this.logger.setDebugEnabled(this.config.enableDebugLog);
        this.decorationManager.updateDecorationStyle(this.config);

        // 初始化活动编辑器
        this.activeEditor = vscode.window.activeTextEditor;

        this.logger.info('扩展管理器初始化完成');
        this.setupEventListeners(context);
        this.performInitialAnalysis();
    }

    /**
     * 设置事件监听器
     */
    private setupEventListeners(context: vscode.ExtensionContext): void {
        // 监听配置变化
        this.disposables.push(
            ConfigManager.onConfigChanged(newConfig => {
                this.onConfigChanged(newConfig);
            })
        );

        // 监听活动编辑器变化
        this.disposables.push(
            vscode.window.onDidChangeActiveTextEditor(editor => {
                this.onActiveEditorChanged(editor);
            })
        );

        // 监听文档内容变化
        this.disposables.push(
            vscode.workspace.onDidChangeTextDocument(event => {
                this.onDocumentChanged(event);
            })
        );

        // 监听文档保存
        this.disposables.push(
            vscode.workspace.onDidSaveTextDocument(document => {
                this.onDocumentSaved(document);
            })
        );

        // 监听文档打开
        this.disposables.push(
            vscode.workspace.onDidOpenTextDocument(document => {
                this.onDocumentOpened(document);
            })
        );

        // 监听语言服务器状态变化
        this.disposables.push(
            vscode.languages.onDidChangeDiagnostics(event => {
                this.onDiagnosticsChanged(event);
            })
        );

        // 注册命令
        this.registerCommands(context);

        // 将所有 disposables 添加到 context
        context.subscriptions.push(...this.disposables);
    }

    /**
     * 注册扩展命令
     */
    private registerCommands(context: vscode.ExtensionContext): void {
        // 手动刷新命令
        const refreshCommand = vscode.commands.registerCommand(
            'phpZeroRefHighlighter.refresh',
            () => this.forceRefresh()
        );

        // 切换启用状态命令
        const toggleCommand = vscode.commands.registerCommand(
            'phpZeroRefHighlighter.toggle',
            () => this.toggleEnabled()
        );

        // 显示日志命令
        const showLogsCommand = vscode.commands.registerCommand(
            'phpZeroRefHighlighter.showLogs',
            () => this.logger.show()
        );

        context.subscriptions.push(refreshCommand, toggleCommand, showLogsCommand);
        this.logger.debug('扩展命令已注册');
    }

    /**
     * 配置变化处理
     */
    private onConfigChanged(newConfig: ExtensionConfig): void {
        this.logger.debug('配置已更改');
        const oldEnabled = this.config.enabled;

        this.config = newConfig;
        this.logger.setDebugEnabled(newConfig.enableDebugLog);
        this.decorationManager.updateDecorationStyle(newConfig);

        // 如果启用状态发生变化
        if (oldEnabled !== newConfig.enabled) {
            if (newConfig.enabled) {
                this.logger.info('扩展已启用');
                this.scheduleUpdate(false);
            } else {
                this.logger.info('扩展已禁用');
                this.decorationManager.clearAllDecorations();
            }
        } else if (newConfig.enabled) {
            // 配置更改但仍然启用，重新分析
            this.scheduleUpdate(false);
        }
    }

    /**
     * 活动编辑器变化处理
     */
    private onActiveEditorChanged(editor: vscode.TextEditor | undefined): void {
        this.activeEditor = editor;

        if (editor && PhpAnalyzer.isPhpDocument(editor.document)) {
            this.logger.debug(`切换到 PHP 文档: ${editor.document.fileName}`);
            // 短暂延迟以确保编辑器完全加载
            this.scheduleUpdate(true, 200);
        }
    }

    /**
     * 文档内容变化处理
     */
    private onDocumentChanged(event: vscode.TextDocumentChangeEvent): void {
        if (this.activeEditor &&
            event.document === this.activeEditor.document &&
            PhpAnalyzer.isPhpDocument(event.document)) {

            // 使用节流来避免频繁更新
            this.scheduleUpdate(true, this.config.throttleDelay);
        }
    }

    /**
     * 文档保存处理
     */
    private onDocumentSaved(document: vscode.TextDocument): void {
        if (this.activeEditor &&
            this.activeEditor.document === document &&
            PhpAnalyzer.isPhpDocument(document)) {

            this.logger.debug(`文档已保存: ${document.fileName}`);
            // 保存时立即更新
            this.scheduleUpdate(false);
        }
    }

    /**
     * 文档打开处理
     */
    private onDocumentOpened(document: vscode.TextDocument): void {
        if (PhpAnalyzer.isPhpDocument(document) &&
            this.activeEditor &&
            this.activeEditor.document === document) {

            this.logger.debug(`PHP 文档已打开: ${document.fileName}`);
            // 延迟处理以确保文档完全加载
            this.scheduleUpdate(true, 500);
        }
    }

    /**
     * 诊断信息变化处理
     */
    private onDiagnosticsChanged(event: vscode.DiagnosticChangeEvent): void {
        if (this.activeEditor &&
            event.uris.some(uri => uri.toString() === this.activeEditor?.document.uri.toString()) &&
            PhpAnalyzer.isPhpDocument(this.activeEditor.document)) {

            // 语言服务器更新了诊断信息，可能已准备就绪
            this.scheduleUpdate(true, 200);
        }
    }

    /**
     * 执行初始分析
     */
    private performInitialAnalysis(): void {
        if (this.activeEditor && PhpAnalyzer.isPhpDocument(this.activeEditor.document)) {
            this.logger.debug('执行初始分析');
            // 延迟执行以确保语言服务器准备就绪
            this.scheduleUpdate(true, 2000);
        }
    }

    /**
     * 调度更新
     */
    private scheduleUpdate(useThrottle: boolean, delay?: number): void {
        if (!this.config.enabled) {
            return;
        }

        // 清除之前的定时器
        if (this.updateTimeout) {
            clearTimeout(this.updateTimeout);
            this.updateTimeout = undefined;
        }

        const actualDelay = delay ?? (useThrottle ? this.config.throttleDelay : 0);

        if (actualDelay > 0) {
            this.updateTimeout = setTimeout(() => {
                void this.updateDecorations();
            }, actualDelay);
        } else {
            void this.updateDecorations();
        }
    }

    /**
     * 更新装饰
     */
    private async updateDecorations(): Promise<void> {
        if (!this.config.enabled ||
            !this.activeEditor ||
            !PhpAnalyzer.isPhpDocument(this.activeEditor.document) ||
            this.isUpdating) {
            return;
        }

        this.isUpdating = true;
        const editor = this.activeEditor; // 保存引用

        try {
            this.logger.debug(`开始更新装饰: ${editor.document.fileName}`);

            const result = await this.analyzer.analyzeDocument(editor.document, this.config);

            // 确保编辑器没有切换
            if (this.activeEditor === editor) {
                this.decorationManager.applyDecorations(editor, result.zeroRefRanges);

                if (result.hasErrors) {
                    this.logger.warn(`分析完成但有错误: ${result.errors.length} 个错误`);
                } else {
                    this.logger.debug(`装饰更新完成: ${result.zeroRefRanges.length} 个零引用函数`);
                }
            }

        } catch (error) {
            this.logger.error('更新装饰失败', error instanceof Error ? error : undefined);
        } finally {
            this.isUpdating = false;
        }
    }

    /**
     * 强制刷新
     */
    private async forceRefresh(): Promise<void> {
        this.logger.info('执行强制刷新');
        await this.updateDecorations();
        vscode.window.showInformationMessage('PHP Zero Reference Highlighter 已刷新');
    }

    /**
     * 切换启用状态
     */
    private async toggleEnabled(): Promise<void> {
        const config = vscode.workspace.getConfiguration('phpZeroRefHighlighter');
        const currentEnabled = config.get<boolean>('enabled', true);

        await config.update('enabled', !currentEnabled, vscode.ConfigurationTarget.Global);

        const status = !currentEnabled ? '已启用' : '已禁用';
        vscode.window.showInformationMessage(`PHP Zero Reference Highlighter ${status}`);
    }

    /**
     * 释放资源
     */
    public dispose(): void {
        this.logger.info('扩展管理器正在释放资源');

        // 清除定时器
        if (this.updateTimeout) {
            clearTimeout(this.updateTimeout);
        }

        // 释放所有 disposables
        this.disposables.forEach(disposable => disposable.dispose());
        this.disposables.length = 0;

        // 释放管理器
        this.decorationManager.dispose();
        this.logger.dispose();
    }
}